
/******************/
/* TP3 - GRUPO 13 */
/******************/
/* Andre Bonna    */
/* Artur Gontijo  */
/* Ivo Trivella   */
/******************/


#include <stdio.h>
#include <stdio_ext.h> /* Biblioteca usada para a funcao '__fpurge()' */
#include <stdlib.h>
#include <string.h>
#include <ctype.h>


/* ------------------------------ DEFINES ------------------------------- */

/* Defines dos nomes dos arquivos*/
#define BASE "base13.dat" /* Base de Dados */

#define INDPRIM "pk.ind" /* Indice Primario */

#define TITPK "pktitulo.ind" /* PK: Titulo */
#define TITSK "sktitulo.ind" /* SK: Titulo */

#define TIPPK "pktipo.ind" /* PK: Tipo */
#define TIPSK "sktipo.ind" /* SK: Tipo */

#define AUTPK "pkautor.ind" /* PK: Autor */
#define AUTSK "skautor.ind" /* SK: Autor */

#define ANOPK "pkano.ind" /* PK: Ano */
#define ANOSK "skano.ind" /* SK: Ano */

#define AVAILLIST "avail.ind" /* Avail List: Apontador para o primeiro */

#define LISTAHTML "lista.html" /* Listagem Completa em HTML */
#define BUSCAHTML "busca.html" /* Resultado de Busca em HTML */

/* Numero inicial de alocacao de memoria */
#define NALLOC 20

/* Numero de bytes do numero de posicao relativa nos indices */
#define TAMPOSREL 4

/* Tamanho da string de nome de arquivo */
#define NOMEARQTAM 20

/* Define o tamanho do registro: 450 bytes */
#define REGTAM 450

/* Definicoes dos numeros maximos de caracteres de cada campo do registro */
#define MAX_TIT 200
#define MAX_TIP 100
#define MAX_AUT 125
#define MAX_ANO 4
#define MAX_VAL 12
#define MAX_IMG 9

#define IMG_EXT 3


/* ------------------------------ ESTRUTURAS ------------------------------ */

/* ------------- REGISTRO ------------ */

typedef struct {
  char titulo[MAX_TIT+1];
  char tipo[MAX_TIP+1];
  char autor[MAX_AUT+1];
  char ano[MAX_ANO+1];
  int valor;
  char imagem[MAX_IMG+1];
} reg;

/* ------------- INDICES ------------ */

typedef struct {
  char pk[MAX_TIT+1];
  char sk[MAX_TIT+1];
  int pos; /* Apontador para a posicao no arquivo de PK relacionado */
} tipocelsk;

typedef struct {
  tipocelsk *listask;
  int listasktam; /* Tamanho da lista de chaves secundarias */
  int listapktam; /* Tamanho da lista de chaves primarias relacionadas */
} tipoindice;


/* ------------------------------ FUNCOES ------------------------------ */

/* Funcao auxiliar para a busca */
int aux_bsearch(const void* key, const void* elem);

/* Imprime o menu principal de funcionalidades do programa */
void menup(FILE **basept, FILE **arq, reg *dados, tipoindice *pk, tipoindice *titulo, tipoindice *tipo, tipoindice *autor, tipoindice *ano, int *alocados);

/* Adiciona um registro a base de dados: */
/* Armazena os dados na struct, e os grava no arquivo 'base13.dat'  */
void add(FILE **basept, FILE **arq, reg *dados, tipoindice *pk, tipoindice *titulo, tipoindice *tipo, tipoindice *autor, tipoindice *ano, int *alocados);

/* Remove um registro da base de dados  */
void remocao(FILE **basept, FILE **arq, reg *dados, tipoindice *pk, tipoindice *titulo, tipoindice *tipo, tipoindice *autor, tipoindice *ano, tipocelsk *resbusca, int *alocados);

/* Carrega o indice do arquivo .ind para a memoria */
void ind2ram(FILE **arq, tipoindice *pk, char *nomearq, int *alocados);

/* Guarda os dados da estrutura, que estao na memoria, no arquivo .ind */
void ram2ind(FILE **arq, tipoindice *pk, char *nomearq);

/* Funcao usada pelo qsort para comparar strings */
int compara(const void *a, const void *b);

/* Ordena o indice na memoria por ordem alfabetica do titulo */
void ordenaindice(tipoindice *pk);

/* Cria os indices a partir do banco de dados */
void criaindice(FILE **basept, FILE **arq, tipoindice *pk, tipoindice *titulo, tipoindice *tipo, tipoindice *autor, tipoindice *ano, int *alocados);

/* Atualiza os indices quando ha insercao na base de dados, e os ordena */
void insereindice(FILE **arq, reg *dados, tipoindice *pk, tipoindice *titulo, tipoindice *tipo, tipoindice *autor, tipoindice *ano);

/* Busca uma obra por chave primaria (campo 'titulo') */
tipocelsk * buscat(tipoindice *pk, char *target);

/* Menu para as Diversas Buscas  */
void menubusca(FILE **basept, FILE **arq, reg *dados, tipoindice *pk, tipoindice *titulo, tipoindice *tipo, tipoindice *autor, tipoindice *ano, int *alocados);

/* Lista todos os registros existentes no banco de dados, imprimindo em um arquivo HTML 'lista.html' */
void lista(FILE **basept, tipoindice *pk);

/* Imprime o resultado da busca por chave secundaria no arquivo HTML apontado por 'arq': 'buscask.html' */
void imprimeBusca(FILE **basept, FILE *arq, int NRR);

/* --------------------------------------------------------------------- */
